package com.lms.logistics_management_system.service;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lms.logistics_management_system.common.Constants;
import com.lms.logistics_management_system.controller.dto.DepartmentAndItemDetailDto;
import com.lms.logistics_management_system.controller.dto.DepartmentRankDetailDto;
import com.lms.logistics_management_system.controller.dto.DepartmentRankDto;
import com.lms.logistics_management_system.entity.Doctor;
import com.lms.logistics_management_system.entity.Item;
import com.lms.logistics_management_system.entity.QueueCondition;
import com.lms.logistics_management_system.exception.ServiceException;
import com.lms.logistics_management_system.mapper.ItemMapper;
import com.lms.logistics_management_system.mapper.QueueConditionMapper;
import com.lms.logistics_management_system.mapper.ReservationItemMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class QueueConditionService extends ServiceImpl<QueueConditionMapper, QueueCondition> {
    @Autowired
    private QueueConditionMapper queueConditionMapper;

    @Autowired
    private ReservationItemMapper reservationItemMapper;

    @Autowired
    private ItemMapper itemMapper;

    // 新增排队信息
    public boolean addQueueCondition(Integer reservationId){
        try {
            if(queueConditionMapper.getQueueByReservationId(reservationId) == null){
                // 没在排队
                if (queueConditionMapper.getByReservationId(reservationId) != null) {
                    // 有记录
                    return updateById(new QueueCondition(reservationId, 0, 0, LocalDateTime.now()));
                } else {
                    // 没记录
                    return save(new QueueCondition(reservationId, 0, 0, LocalDateTime.now()));
                }
            } else {
                // 在排队
                return updateById(new QueueCondition(reservationId, 0, 0, LocalDateTime.now()));
            }
        }catch (Exception se){
            System.out.println(se);
            throw new ServiceException(Constants.CODE_500,"排队信息新增失败！");
        }
    }

    // 更新排队信息
    public boolean updateQueueCondition(QueueCondition queueCondition) {
        try {
            if(queueConditionMapper.getByReservationId(queueCondition.getReservationId()) != null){
                queueCondition.setQueueConditionEntryTime(LocalDateTime.now());
                //有openid代表更新排队信息
                return queueConditionMapper.updateQueueCondition(queueCondition);
            }
        }catch (Exception se){
            System.out.println(se);
            throw new ServiceException(Constants.CODE_500,"排队信息修改失败！");
        }

        //没有openid代表没签到
        throw new ServiceException(Constants.CODE_500, "未签到!");
    }

    public Integer queueNext(Integer department_id, Integer room_id){
        try {
            QueueCondition first = queueConditionMapper.getFirst(department_id, room_id);
            if (first != null) {
                // 把第一人从队伍中踢出
                first.setDepartmentId(0);
                first.setRoomId(0);
                updateQueueCondition(first);
                return first.getReservationId();
            }
            return null;

        } catch (Exception se) {
            System.out.println(se);
            throw new ServiceException(Constants.CODE_500,"获取下一人失败！");
        }

    }

    public ArrayList<DepartmentRankDto> allDepartmentRank(Integer reservationId) {
        ArrayList<DepartmentRankDto> departmentRank = new ArrayList<>();
        try {
            ArrayList<DepartmentRankDetailDto> details = queueConditionMapper.allDepartmentRank(reservationId);
            if (!details.isEmpty()) {
                DepartmentRankDto departmentRankDto = new DepartmentRankDto();
                departmentRankDto.setDepartmentName(details.get(0).getDepartmentName());
                departmentRankDto.setQueueSum(details.get(0).getQueueSum());
                ArrayList<String> t = new ArrayList<String>();
                t.add(details.get(0).getItemName());
                departmentRankDto.setItemNames(t);
                departmentRank.add(departmentRankDto);
            }

            int start = 0;
            for (int i = 1; i < details.size(); i++) {
                DepartmentRankDetailDto detail = details.get(i);
                if (detail.getItemName() == null && start == 0) {
                    departmentRank.sort(new Comparator<DepartmentRankDto>() {
                        @Override
                        public int compare(DepartmentRankDto d1, DepartmentRankDto d2) {
                            // TODO Auto-generated method stub
                            if (d1.getQueueSum() > d2.getQueueSum()) {
                                return 1;
                            } else if (d1.getQueueSum() < d2.getQueueSum()) {
                                return -1;
                            }
                            return 0;
                        }
                    });
                    start = departmentRank.size();
                }
                if (Objects.equals(departmentRank.get(departmentRank.size() - 1).getDepartmentName(), detail.getDepartmentName())) {
                    departmentRank.get(departmentRank.size() - 1).getItemNames().add(detail.getItemName());
                }
                else {
                    DepartmentRankDto departmentRankDto = new DepartmentRankDto();
                    departmentRankDto.setDepartmentName(detail.getDepartmentName());
                    departmentRankDto.setQueueSum(detail.getQueueSum());
                    ArrayList<String> t = new ArrayList<String>();
                    t.add(detail.getItemName());
                    departmentRankDto.setItemNames(t);
                    departmentRank.add(departmentRankDto);
                }
            }
            departmentRank.subList(start, departmentRank.size()).sort(new Comparator<DepartmentRankDto>() {
                @Override
                public int compare(DepartmentRankDto d1, DepartmentRankDto d2) {
                    // TODO Auto-generated method stub
                    if (d1.getQueueSum() > d2.getQueueSum()) {
                        return 1;
                    } else if (d1.getQueueSum() < d2.getQueueSum()) {
                        return -1;
                    }
                    return 0;
                }
            });
            return departmentRank;
        } catch (Exception se) {
            System.out.println(se);
            throw new ServiceException(Constants.CODE_500, "获取科信息失败！");
        }
    }

    public void export(Integer reservationId, HttpServletResponse response) throws Exception {
        //从数据库查出数据
        List<DepartmentAndItemDetailDto> dataList = queueConditionMapper.allDepartmentAndItemDetail(reservationId);
        List<List<Object>> resultList = new ArrayList<>();

        for (DepartmentAndItemDetailDto dto : dataList) {
            List<Object> rowList = new ArrayList<>();
            rowList.add(dto.getDepartmentId());
            rowList.add(dto.getDepartmentName());
            rowList.add(dto.getItemId());
            rowList.add(dto.getItemName());
            rowList.add(dto.getItemPrice());

            resultList.add(rowList);
        }

        //创建工具类writer，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义标题名
        writer.addHeaderAlias("departmentId","科号");
        writer.addHeaderAlias("departmentName","科名");
        writer.addHeaderAlias("itemId","项目号");
        writer.addHeaderAlias("itemName","项目名");
        writer.addHeaderAlias("itemPrice","项目价格");
        //将list对象一次性写入到excel中，使用默认样式，强制输出标题
        writer.write(resultList,true);
        //设置浏览器响应的格式固定写法
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        Date nowtime=new Date();
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
        String nowtimstr=sdf.format(nowtime);//Date类型转换为字符串
        String fileName = URLEncoder.encode("项目信息"+nowtimstr,"UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");

        //获取输出流
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out,true);
        out.close();
        writer.close();
    }
}
